package com.guofeng.server;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.guofeng.constant.AuthConstant;
import com.guofeng.entity.Member;
import com.guofeng.entity.SysUser;
import com.guofeng.mapper.MemberMapper;
import com.guofeng.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: guofeng
 * @Date: 2021/08/18/14:10
 * @Description:
 */
@Slf4j
@Component
public class UserDetailsServerImpl implements UserDetailsService {


    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;


    /**
     * 和数据库结合的真实登录
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.拿到request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        // 2. 拿到header
        String header = request.getHeader(AuthConstant.LOGIN_TYPE);
        if (!StringUtils.hasText(header)) {
            // 搞一个默认值 就是前台用户
            header = AuthConstant.MEMBER;
        }
        switch (header) {
            //前台用户
            case AuthConstant.MEMBER:
                // 前台查询数据库
                Member member = memberMapper.selectOne(new LambdaQueryWrapper<Member>()
                        .eq(Member::getUsername, username));

                return new User(member.getId()+"-"+member.getUsername(),passwordEncoder.encode(member.getPassword()),null);
            //后台用户
            case AuthConstant.SYS_USER:
                //查询数据库存在不存在此人
                SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
                );
                List<SimpleGrantedAuthority> authorities = null;
                if (!ObjectUtils.isEmpty(sysUser)) {
                    //查询用户权限
                    List<String> auths = sysUserMapper.getUserAuthByUserId(sysUser.getId());
                    //封装权限
                    if (!CollectionUtils.isEmpty(auths)) {
                        authorities = new ArrayList<>();
                        for (String auth : auths) {
                           authorities.add(new SimpleGrantedAuthority(auth));
                        }
                    }
                }
                //返回用户信息
                return new User(sysUser.getId()+"-"+sysUser.getUsername(), passwordEncoder.encode(sysUser.getPassword()),authorities);
            default:
                return null;
        }
    }

    /**
     * 这里模拟数据结合登录
     * 这里面 我们把前后台登录 都结合起来
     *
     * @param
     * @return
     * @throws UsernameNotFoundException
     */
/*    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 模拟一个数据库
        HashMap<String, User> userHashMap = new HashMap<>(4);

        //前端用户
        ArrayList<SimpleGrantedAuthority> testAuths = new ArrayList<>(4);
        testAuths.add(new SimpleGrantedAuthority("test:query"));
        testAuths.add(new SimpleGrantedAuthority("test:find"));
        User test = new User("test", passwordEncoder.encode("test"), testAuths);
        //后端管理员
        ArrayList<SimpleGrantedAuthority> adminAuths = new ArrayList<>(4);
        adminAuths.add(new SimpleGrantedAuthority("sys:add"));
        adminAuths.add(new SimpleGrantedAuthority("sys:del"));
        User admin = new User("admin", passwordEncoder.encode("admin"), adminAuths);
        //添加到 HashMap中
        userHashMap.put("user", test);
        userHashMap.put("sysUser", admin);

        // 我们可以在请求头里面加一个字段
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        // 拿到header
        String loginType = request.getHeader("login_type");

        if (!StringUtils.hasText(loginType)) {
            // 也可以直接 return null
            loginType = "user";
        }
        switch (loginType) {
            case "user":
                // 如果是前台 就查询前台的表
                log.info("前台用户");
                return userHashMap.get(loginType);
            case "sysUser":
                // 如果后台 我们就查询后台的表
                log.info("后台管理员");
                return userHashMap.get(loginType);
            default:
                log.info("匿名用户");
                return null;
        }
    }*/
}
